﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml.Serialization;
using LogClass;

namespace PrinterCommunication
{
    public class Printer
    {
        public enum QueueStatus
        {
            PowerSave, ServerUnknown, DoorOpen, OutOfMemory,
            PagePunt, NoToner, TonerLow, WarmingUp,
            Initializing, Processing, Waiting, NotAvailable,
            OutputBinFull, Busy, IOActive, Offline,
            PaperProblem, ManualFeed, PaperOut, PaperJam,
            PendingDeletion, Paused, None, Printing, Error
        };

        public string name { get; set; }
        public string fullName { get; set; }
        public bool hasPaperProblem { get; set; }
        public bool hasToner { get; set; }
        public string hostingPrintServer { get; set; }
        public bool isInError { get; set; }
        public bool isInitializing { get; set; }
        public bool isManualFeedRequired { get; set; }
        public bool isNotAvailable { get; set; }
        public bool isOffline { get; set; }
        public bool isOutOfMemory { get; set; }
        public bool isOutOfPaper { get; set; }
        public bool isOutputBinFull { get; set; }
        public bool isPaperJammed { get; set; }
        public bool isPaused { get; set; }
        public bool isTonerLow { get; set; }
        public bool isWarmingUp { get; set; }
        public string location { get; set; }
        public bool needUserIntervention { get; set; }
        public int numberOfJobs { get; set; }
        public QueueStatus queueStatus { get; set; }
        public string shareName { get; set; }
        public int startTimeOfDay { get; set; }
        public int untilTimeOfDay { get; set; }
        public string image { get; set; }
        public PrintTicket printTicket { get; set; }
        public PrinterCapability printerCapability { get; set; }

        public Printer()
        {
        }

        public Printer(XElement xElement)
        {
            name = xElement.Attribute("Name").Value;
            fullName = xElement.Attribute("FullName").Value;
            hasPaperProblem = Convert.ToBoolean(xElement.Attribute("HasPaperProblem").Value);
            hasToner = Convert.ToBoolean(xElement.Attribute("HasToner").Value);
            hostingPrintServer = xElement.Attribute("HostingPrintServer").Value;
            isInError = Convert.ToBoolean(xElement.Attribute("IsInError").Value);
            isInitializing = Convert.ToBoolean(xElement.Attribute("IsInitializing").Value);
            isManualFeedRequired = Convert.ToBoolean(xElement.Attribute("IsManualFeedRequired").Value);
            isNotAvailable = Convert.ToBoolean(xElement.Attribute("IsNotAvailable").Value);
            isOffline = Convert.ToBoolean(xElement.Attribute("IsOffline").Value);
            isOutOfMemory = Convert.ToBoolean(xElement.Attribute("IsOutOfMemory").Value);
            isOutOfPaper = Convert.ToBoolean(xElement.Attribute("IsOutOfPaper").Value);
            isOutputBinFull = Convert.ToBoolean(xElement.Attribute("IsOutputBinFull").Value);
            isPaperJammed = Convert.ToBoolean(xElement.Attribute("IsPaperJammed").Value);
            isPaused = Convert.ToBoolean(xElement.Attribute("IsPaused").Value);
            isTonerLow = Convert.ToBoolean(xElement.Attribute("IsTonerLow").Value);
            isWarmingUp = Convert.ToBoolean(xElement.Attribute("IsWarmingUp").Value);
            location = xElement.Attribute("Location").Value;
            needUserIntervention = Convert.ToBoolean(xElement.Attribute("NeedUserIntervention").Value);
            numberOfJobs = Convert.ToInt32(xElement.Attribute("NumberOfJobs").Value);
            if (xElement.Attribute("QueueStatus").Value != "")
                queueStatus = (QueueStatus)Enum.Parse(typeof(QueueStatus),
                    xElement.Attribute("QueueStatus").Value, true);
            else
                queueStatus = QueueStatus.None;
            shareName = xElement.Attribute("ShareName").Value;
            startTimeOfDay = Convert.ToInt32(xElement.Attribute("StartTimeOfDay").Value);
            untilTimeOfDay = Convert.ToInt32(xElement.Attribute("UntilTimeOfDay").Value);
            image = null;
        }

        public XElement xPrinter
        {
            get
            {
                return new XElement("Printer",
                new XAttribute("Name", name),
                new XAttribute("FullName", fullName),
                new XAttribute("HasPaperProblem", hasPaperProblem),
                new XAttribute("HasToner", hasToner),
                new XAttribute("HostingPrintServer", hostingPrintServer),
                new XAttribute("IsInError", isInError),
                new XAttribute("IsInitializing", isInitializing),
                new XAttribute("IsManualFeedRequired", isManualFeedRequired),
                new XAttribute("IsNotAvailable", isNotAvailable),
                new XAttribute("IsOffline", isOffline),
                new XAttribute("IsOutOfMemory", isOutOfMemory),
                new XAttribute("IsOutOfPaper", isOutOfPaper),
                new XAttribute("IsOutputBinFull", isOutputBinFull),
                new XAttribute("IsPaperJammed", isPaperJammed),
                new XAttribute("IsPaused", isPaused),
                new XAttribute("IsTonerLow", isTonerLow),
                new XAttribute("IsWarmingUp", isWarmingUp),
                new XAttribute("Location", location),
                new XAttribute("NeedUserIntervention", needUserIntervention),
                new XAttribute("NumberOfJobs", numberOfJobs),
                new XAttribute("QueueStatus", queueStatus),
                new XAttribute("ShareName", shareName),
                new XAttribute("StartTimeOfDay", startTimeOfDay),
                new XAttribute("UntilTimeOfDay", untilTimeOfDay));
            }
        }

        public override string ToString()
        {
            string sXml = "";
            sXml = @"<PRINTER Name=""" + this.name + @"""";
            sXml += (" FullName=\"" + this.fullName + @"""");
            sXml += (" HasPaperProblem=\"" + this.hasPaperProblem + @"""");
            sXml += (" HasToner=\"" + this.hasToner + @"""");
            sXml += (" HostingPrintServer=\"" + this.hostingPrintServer + @"""");
            sXml += (" IsInError=\"" + this.isInError + @"""");
            sXml += (" IsInitializing=\"" + this.isInitializing + @"""");
            sXml += (" IsManualFeedRequired=\"" + this.isManualFeedRequired + @"""");
            sXml += (" IsNotAvailable=\"" + this.isNotAvailable + @"""");
            sXml += (" IsOffline=\"" + this.isOffline + @"""");
            sXml += (" IsOutOfMemory=\"" + this.isOutOfMemory + @"""");
            sXml += (" IsOutOfPaper=\"" + this.isOutOfPaper + @"""");
            sXml += (" IsOutputBinFull=\"" + this.isOutputBinFull + @"""");
            sXml += (" IsPaperJammed=\"" + this.isPaperJammed + @"""");
            sXml += (" IsPaused=\"" + this.isPaused + @"""");
            sXml += (" IsTonerLow=\"" + this.isTonerLow + @"""");
            sXml += (" IsWarmingUp=\"" + this.isWarmingUp + @"""");
            sXml += (" Location=\"" + this.location + @"""");
            sXml += (" NeedUserIntervention=\"" + this.needUserIntervention + @"""");
            sXml += (" NumberOfJobs=\"" + this.numberOfJobs + @"""");
            sXml += (" QueueStatus=\"" + this.queueStatus + @"""");
            sXml += (" ShareName=\"" + this.shareName + @"""");
            sXml += (" StartTimeOfDay=\"" + this.startTimeOfDay + @"""");
            sXml += (" UntilTimeOfDay=\"" + this.untilTimeOfDay + @"""");
            sXml += " />";
            return "<PRINTERS>" + Environment.NewLine + sXml + Environment.NewLine + "</PRINTERS>";
        }
    }

    public class PrintTicket
    {
        public enum Collation
        {
            Unknown, Collated, Uncollated
        };
        public enum DeviceFontSubstitution
        {
            Unknown, Off, On
        };
        public enum Duplexing
        {
            Unknown, OneSided, TwoSidedShortEdge, TwoSidedLongEdge
        };
        public enum InputBin
        {
            Unknown, AutoSelect, Cassette, Tractor, AutoSheetFeeder, Manual
        };
        public enum OutputColor
        {
            Unknown, Color, Grayscale, Monochrome
        };
        public enum OutputQuality
        {
            Unknown, Automatic, Draft, Fax, High, Normal, Photographic, Text
        };
        public enum PageBorderless
        {
            Unknown, Borderless, None
        };
        public enum PageOrder
        {
            Unknown, Standard, Reverse
        };
        public enum PageOrientation
        {
            Unknown, Landscape, Portrait, ReverseLandscape, ReversePortrait
        };
        public enum PageResolution
        {
            Unknown, Default, Draft, High, Normal, Other
        };
        public enum PhotoPrintingIntent
        {
            Unknown, None, PhotoBest, PhotoDraft, PhotoStandard
        };

        public Collation collation { get; set; }
        public Nullable<Int32> copyCount { get; set; }
        public DeviceFontSubstitution deviceFontSubstitution { get; set; }
        public Duplexing duplexing { get; set; }
        public InputBin inputBin { get; set; }
        public OutputColor outputColor { get; set; }
        public OutputQuality outputQuality { get; set; }
        public PageBorderless pageBorderless { get; set; }
        public string pageMediaSizeName { get; set; }
        public Nullable<double> pageMediaSizeHeight { get; set; }
        public Nullable<double> pageMediaSizeWidth { get; set; }
        public PageOrder pageOrder { get; set; }
        public PageOrientation pageOrientation { get; set; }
        public PageResolution qualitativePageResolution { get; set; }
        public Nullable<Int32> pageResolutionDpiX { get; set; }
        public Nullable<Int32> pageResolutionDpiY { get; set; }
        public Nullable<Int32> pageScalingFactor { get; set; }
        public Nullable<Int32> pagesPerSheet { get; set; }
        public PhotoPrintingIntent photoPrintingIntent { get; set; }

        public PrintTicket()
        {
        }

        public PrintTicket(XElement xElement)
        {
            if ((xElement.Attribute("Collation") != null) && (xElement.Attribute("Collation").Value != ""))
                collation = (Collation)Enum.Parse(typeof(Collation),
                    xElement.Attribute("Collation").Value, true);
            else
                collation = Collation.Unknown;
            if ((xElement.Attribute("CopyCount") != null) && (xElement.Attribute("CopyCount").Value != ""))
                copyCount = Convert.ToInt32(xElement.Attribute("CopyCount").Value);
            else
                copyCount = null;
            if ((xElement.Attribute("DeviceFontSubstitution") != null) && (xElement.Attribute("DeviceFontSubstitution").Value != ""))
                deviceFontSubstitution = (DeviceFontSubstitution)Enum.Parse(typeof(DeviceFontSubstitution),
                    xElement.Attribute("DeviceFontSubstitution").Value, true);
            else
                deviceFontSubstitution = DeviceFontSubstitution.Unknown;
            if ((xElement.Attribute("Duplexing") != null) && (xElement.Attribute("Duplexing").Value != ""))
                duplexing = (Duplexing)Enum.Parse(typeof(Duplexing),
                    xElement.Attribute("Duplexing").Value, true);
            else
                duplexing = Duplexing.Unknown;
            if ((xElement.Attribute("InputBin") != null) && (xElement.Attribute("InputBin").Value != ""))
                inputBin = (InputBin)Enum.Parse(typeof(InputBin),
                    xElement.Attribute("InputBin").Value, true);
            else
                inputBin = InputBin.Unknown;
            if ((xElement.Attribute("OutputColor") != null) && (xElement.Attribute("OutputColor").Value != ""))
                outputColor = (OutputColor)Enum.Parse(typeof(OutputColor),
                    xElement.Attribute("OutputColor").Value, true);
            else
                outputColor = OutputColor.Unknown;
            if ((xElement.Attribute("OutputQuality") != null) && (xElement.Attribute("OutputQuality").Value != ""))
                outputQuality = (OutputQuality)Enum.Parse(typeof(OutputQuality),
                    xElement.Attribute("OutputQuality").Value, true);
            else
                outputQuality = OutputQuality.Unknown;
            if ((xElement.Attribute("PageBorderless") != null) && (xElement.Attribute("PageBorderless").Value != ""))
                pageBorderless = (PageBorderless)Enum.Parse(typeof(PageBorderless),
                    xElement.Attribute("PageBorderless").Value, true);
            else
                pageBorderless = PageBorderless.Unknown;
            if (xElement.Attribute("PageMediaSizeName") != null)
            {
                pageMediaSizeName = xElement.Attribute("PageMediaSizeName").Value;
                if ((xElement.Attribute("PageMediaSizeHeight") != null) && (xElement.Attribute("PageMediaSizeHeight").Value != ""))
                    pageMediaSizeHeight = Convert.ToDouble(xElement.Attribute("PageMediaSizeHeight").Value);
                else
                    pageMediaSizeHeight = null;
                if ((xElement.Attribute("PageMediaSizeWidth") != null) && (xElement.Attribute("PageMediaSizeWidth").Value != ""))
                    pageMediaSizeWidth = Convert.ToDouble(xElement.Attribute("PageMediaSizeWidth").Value);
                else
                    pageMediaSizeWidth = null;
                
            }
            else
            {
                pageMediaSizeName = null;
                pageMediaSizeHeight = null;
                pageMediaSizeWidth = null;
            }
            if ((xElement.Attribute("PageOrder") != null) && (xElement.Attribute("PageOrder").Value != ""))
                pageOrder = (PageOrder)Enum.Parse(typeof(PageOrder),
                    xElement.Attribute("PageOrder").Value, true);
            else
                pageOrder = PageOrder.Unknown;
            if ((xElement.Attribute("PageOrientation") != null) && (xElement.Attribute("PageOrientation").Value != ""))
                pageOrientation = (PageOrientation)Enum.Parse(typeof(PageOrientation),
                    xElement.Attribute("PageOrientation").Value, true);
            else
                pageOrientation = PageOrientation.Unknown;
            if ((xElement.Attribute("QualitativePageResolution") != null) && (xElement.Attribute("QualitativePageResolution").Value != ""))
                qualitativePageResolution = (PageResolution)Enum.Parse(typeof(PageResolution),
                    xElement.Attribute("QualitativePageResolution").Value, true);
            else
                qualitativePageResolution = PageResolution.Unknown;
            if ((xElement.Attribute("PageResolutionDpiX") != null) && (xElement.Attribute("PageResolutionDpiX").Value != ""))
                pageResolutionDpiX = Convert.ToInt32(xElement.Attribute("PageResolutionDpiX").Value);
            else
                pageResolutionDpiX = null;
            if ((xElement.Attribute("PageResolutionDpiY") != null) && (xElement.Attribute("PageResolutionDpiY").Value != ""))
                pageResolutionDpiY = Convert.ToInt32(xElement.Attribute("PageResolutionDpiY").Value);
            else
                pageResolutionDpiY = null;
            if ((xElement.Attribute("PageScalingFactor") != null) && (xElement.Attribute("PageScalingFactor").Value != ""))
                pageScalingFactor = Convert.ToInt32(xElement.Attribute("PageScalingFactor").Value);
            else
                pageScalingFactor = null;
            if ((xElement.Attribute("PagesPerSheet") != null) && (xElement.Attribute("PagesPerSheet").Value != ""))
                pagesPerSheet = Convert.ToInt32(xElement.Attribute("PagesPerSheet").Value);
            else
                pagesPerSheet = null;
            if ((xElement.Attribute("PhotoPrintingIntent") != null) && (xElement.Attribute("PhotoPrintingIntent").Value != ""))
                photoPrintingIntent = (PhotoPrintingIntent)Enum.Parse(typeof(PhotoPrintingIntent),
                    xElement.Attribute("PhotoPrintingIntent").Value, true);
            else
                photoPrintingIntent = PhotoPrintingIntent.Unknown;
        }

        public XElement xPrintTicket
        {
            get
            {
                return new XElement("PrintTicket",
                new XAttribute("Collation", collation),
                new XAttribute("CopyCount", copyCount),
                new XAttribute("DeviceFontSubstitution", deviceFontSubstitution),
                new XAttribute("Duplexing", duplexing),
                new XAttribute("InputBin", inputBin),
                new XAttribute("OutputColor", outputColor),
                new XAttribute("OutputQuality", outputQuality),
                new XAttribute("PageBorderless", pageBorderless),
                new XAttribute("PageMediaSizeName", pageMediaSizeName),
                new XAttribute("PageMediaSizeHeight", pageMediaSizeHeight),
                new XAttribute("PageMediaSizeWidth", pageMediaSizeWidth),
                new XAttribute("PageOrder", pageOrder),
                new XAttribute("PageOrientation", pageOrientation),
                new XAttribute("QualitativePageResolution", qualitativePageResolution),
                new XAttribute("PageResolutionDpiX", pageResolutionDpiX),
                new XAttribute("PageResolutionDpiY", pageResolutionDpiY),
                new XAttribute("PageScalingFactor", pageScalingFactor),
                new XAttribute("PagesPerSheet", pagesPerSheet),
                new XAttribute("PhotoPrintingIntent", photoPrintingIntent));
            }
        }

        public override string ToString()
        {
            string sXml = "";
            sXml = @"<PRINTTICKET ";
            sXml += (" Collation=\"" + Convert.ToInt32(this.collation) + @"""");
            sXml += (" CopyCount=\"" + this.copyCount + @"""");
            sXml += (" DeviceFontSubstitution=\"" + this.deviceFontSubstitution + @"""");
            sXml += (" Duplexing=\"" + this.duplexing + @"""");
            sXml += (" InputBin=\"" + this.inputBin + @"""");
            sXml += (" OutputColor=\"" + this.outputColor + @"""");
            sXml += (" OutputQuality=\"" + this.outputQuality + @"""");
            sXml += (" PageBorderless=\"" + this.pageBorderless + @"""");
            if (this.pageMediaSizeName != null)
                sXml += (" PageMediaSizeName=\"" + this.pageMediaSizeName + @"""");
            if (this.pageMediaSizeHeight != null)
                sXml += (" PageMediaSizeHeight=\"" + this.pageMediaSizeHeight + @"""");
            if (this.pageMediaSizeWidth != null)
                sXml += (" PageMediaSizeWidth=\"" + this.pageMediaSizeWidth + @"""");
            sXml += (" PageOrder=\"" + this.pageOrder + @"""");
            sXml += (" PageOrientation=\"" + this.pageOrientation + @"""");
            sXml += (" QualitativePageResolution=\"" + this.qualitativePageResolution + @"""");
            if (this.pageResolutionDpiX != null)
                sXml += (" PageResolutionDpiX=\"" + this.pageResolutionDpiX + @"""");
            if (this.pageResolutionDpiY != null)
                sXml += (" PageResolutionDpiY=\"" + this.pageResolutionDpiY + @"""");
            if (this.pageScalingFactor != null)
                sXml += (" PageScalingFactor=\"" + this.pageScalingFactor + @"""");
            if (this.pagesPerSheet != null)
                sXml += (" PagesPerSheet=\"" + this.pagesPerSheet + @"""");
            sXml += (" PhotoPrintingIntent=\"" + this.photoPrintingIntent + @"""");
            sXml += " />";
            return "<PRINTTICKETS>" + Environment.NewLine + sXml + Environment.NewLine + "</PRINTTICKETS>";
        }
    }

    public class PrinterCapability
    {
        public int collationCapability { get; set; }
        public int maxCopyCount { get; set; }
        public int deviceFontSubstitutionCapability { get; set; }
        public int duplexingCapability { get; set; }
        public int inputBinCapability { get; set; }
        public int outputColorCapability { get; set; }
        public int outputQualityCapability { get; set; }
        public int pageBorderlessCapability { get; set; }
        public int pageOrderCapability { get; set; }
        public int pageOrientationCapability { get; set; }
        public int pageResolutionCapability { get; set; }
        public Nullable<Int32> pageResolutionCapabilityDpiX { get; set; }
        public Nullable<Int32> pageResolutionCapabilityDpiY { get; set; }
        public Nullable<Int32> pageScalingFactorRangeMinimum { get; set; }
        public Nullable<Int32> pageScalingFactorRangeMaximum { get; set; }
        public int photoPrintingIntentCapability { get; set; }
        public string pageImageableAreaOriginHeight { get; set; }
        public string pageImageableAreaOriginWidth { get; set; }
        public string pageImageableAreaExtentHeight { get; set; }
        public string pageImageableAreaExtentWidth { get; set; }
        public string image { get; set; }

        public List<string> sCollation = new List<string> { "Unknown", "Collated", "Uncollated" };
        public List<string> sDeviceFontSubstitution = new List<string> { "Unknown", "Off", "On" };
        public List<string> sDuplexing = new List<string> { "Unknown", "OneSided", "TwoSidedShortEdge", "TwoSidedLongEdge" };
        public List<string> sInputBin = new List<string> { "Unknown", "AutoSelect", "Cassette", "Tractor", "AutoSheetFeeder", "Manual" };
        public List<string> sOutputColor = new List<string> { "Unknown", "Color", "Grayscale", "Monochrome" };
        public List<string> sOutputQuality = new List<string> { "Unknown", "Automatic", "Draft", "Fax", "High", "Normal", "Photographic", "Text" };
        public List<string> sPageBorderless = new List<string> { "Unknown", "Borderless", "None" };
        public List<string> sPageOrder = new List<string> { "Unknown", "Standard", "Reverse" };
        public List<string> sPageOrientation = new List<string> { "Unknown", "Landscape", "Portrait", "ReverseLandscape", "ReversePortrait" };
        public List<string> sPageResolution = new List<string> { "Unknown", "Default", "Draft", "High", "Normal", "Other" };
        public List<string> sPhotoQuality = new List<string> { "Unknown", "None", "PhotoBest", "PhotoDraft", "PhotoStandard" };

        PrinterCapability()
        {
        }

        public PrinterCapability(XElement xElement)
        {
            if (xElement.Attribute("CollationCapability") != null)
                collationCapability = Convert.ToInt32(xElement.Attribute("CollationCapability").Value);
            else
                collationCapability = 0;
            sCollation = AdjustCapability(collationCapability, sCollation);
            if (maxCopyCount != 0)
                maxCopyCount = Convert.ToInt32(xElement.Attribute("maxCopyCount").Value);
            else
                maxCopyCount = 1;
            if (xElement.Attribute("DeviceFontSubstitutionCapability") != null)
                deviceFontSubstitutionCapability = Convert.ToInt32(xElement.Attribute("DeviceFontSubstitutionCapability").Value);
            else
                deviceFontSubstitutionCapability = 0;
            sDeviceFontSubstitution = AdjustCapability(deviceFontSubstitutionCapability, sDeviceFontSubstitution);
            if (xElement.Attribute("DuplexingCapability") != null)
                duplexingCapability = Convert.ToInt32(xElement.Attribute("DuplexingCapability").Value);
            else
                duplexingCapability = 0;
            sDuplexing = AdjustCapability(duplexingCapability, sDuplexing);
            if (xElement.Attribute("InputBinCapability") != null)
                inputBinCapability = Convert.ToInt32(xElement.Attribute("InputBinCapability").Value);
            else
                inputBinCapability = 0;
            sInputBin = AdjustCapability(deviceFontSubstitutionCapability, sInputBin);
            if (xElement.Attribute("OutputColorCapability") != null)
                outputColorCapability = Convert.ToInt32(xElement.Attribute("OutputColorCapability").Value);
            else
                outputColorCapability = 0;
            sOutputColor = AdjustCapability(outputColorCapability, sOutputColor);
            if (xElement.Attribute("OutputQualityCapability") != null)
                outputQualityCapability = Convert.ToInt32(xElement.Attribute("OutputQualityCapability").Value);
            else
                outputQualityCapability = 0;
            sOutputQuality = AdjustCapability(outputQualityCapability, sOutputQuality);
            if (xElement.Attribute("PageBorderlessCapability") != null)
                pageBorderlessCapability = Convert.ToInt32(xElement.Attribute("PageBorderlessCapability").Value);
            else
                pageBorderlessCapability = 0;
            sPageBorderless = AdjustCapability(pageBorderlessCapability, sPageBorderless);
            if (xElement.Attribute("PageOrderCapability") != null)
                pageOrderCapability = Convert.ToInt32(xElement.Attribute("PageOrderCapability").Value);
            else
                pageOrderCapability = 0;
            sPageOrder = AdjustCapability(pageOrderCapability, sPageOrder);
            if (xElement.Attribute("PageOrientationCapability") != null)
                pageOrientationCapability = Convert.ToInt32(xElement.Attribute("PageOrientationCapability").Value);
            else
                pageOrientationCapability = 0;
            sPageOrientation = AdjustCapability(pageOrientationCapability, sPageOrientation);
            pageResolutionCapability = 0;
            pageResolutionCapabilityDpiX = null;
            pageResolutionCapabilityDpiY = null;
            if (xElement.Attribute("PageResolutionCapability") != null)
            {
                pageResolutionCapability = Convert.ToInt32(xElement.Attribute("PageResolutionCapability").Value);
                if (pageResolutionCapability > 0)
                {
                    if (xElement.Attribute("PageResolutionCapabilityDpiX").Value != "")
                        pageResolutionCapabilityDpiX = Convert.ToInt32(xElement.Attribute("PageResolutionCapabilityDpiX").Value);
                    if (xElement.Attribute("PageResolutionCapabilityDpiY").Value != "")
                        pageResolutionCapabilityDpiY = Convert.ToInt32(xElement.Attribute("PageResolutionCapabilityDpiY").Value);
                }
            }
            sPageResolution = AdjustCapability(pageResolutionCapability, sPageResolution);
            if (xElement.Attribute("PageScalingFactorRangeMinimum") != null)
                pageScalingFactorRangeMinimum = Convert.ToInt32(xElement.Attribute("PageScalingFactorRangeMinimum").Value);
            else
                pageScalingFactorRangeMinimum = 100;
            if (xElement.Attribute("PageScalingFactorRangeMaximum") != null)
                pageScalingFactorRangeMaximum = Convert.ToInt32(xElement.Attribute("PageScalingFactorRangeMaximum").Value);
            else
                pageScalingFactorRangeMaximum = 100;
            if (xElement.Attribute("PhotoPrintingIntentCapability") != null)
                photoPrintingIntentCapability = Convert.ToInt32(xElement.Attribute("PhotoPrintingIntentCapability").Value);
            else
                photoPrintingIntentCapability = 0;
            sPhotoQuality = AdjustCapability(photoPrintingIntentCapability, sPhotoQuality);
            if (xElement.Attribute("PageImageableAreaOriginHeight") != null)
            {
                pageImageableAreaOriginHeight = xElement.Attribute("PageImageableAreaOriginHeight").Value;
                pageImageableAreaOriginWidth = xElement.Attribute("PageImageableAreaOriginWidth").Value;
                pageImageableAreaExtentHeight = xElement.Attribute("PageImageableAreaExtentHeight").Value;
                pageImageableAreaExtentWidth = xElement.Attribute("PageImageableAreaExtentWidth").Value;
            }
            else
            {
                pageImageableAreaOriginHeight = "";
                pageImageableAreaOriginWidth = "";
                pageImageableAreaExtentHeight = "";
                pageImageableAreaExtentWidth = "";
            }
        }

        public XElement xPrinterCapability
        {
            get
            {
                return new XElement("PrinterCapability",

                new XAttribute("CollationCapability", collationCapability),
                new XAttribute("MaxCopyCount", maxCopyCount),
                new XAttribute("DeviceFontSubstitutionCapability", deviceFontSubstitutionCapability),
                new XAttribute("DuplexingCapability", duplexingCapability),
                new XAttribute("InputBinCapability", inputBinCapability),
                new XAttribute("OutputColorCapability", outputColorCapability),
                new XAttribute("OutputQualityCapability", outputQualityCapability),
                new XAttribute("PageBorderlessCapability", pageBorderlessCapability),
                new XAttribute("PageOrderCapability", pageOrderCapability),
                new XAttribute("PageOrientationCapability", pageOrientationCapability),
                new XAttribute("PageResolutionCapability", pageResolutionCapability),
                new XAttribute("PageResolutionCapabilityDpiX", pageResolutionCapability),
                new XAttribute("PageResolutionCapabilityDpiY", pageResolutionCapability),
                new XAttribute("PageScalingFactorRangeMinimum", pageScalingFactorRangeMinimum),
                new XAttribute("PageScalingFactorRangeMaximum", pageScalingFactorRangeMaximum),
                new XAttribute("PhotoPrintingIntentCapability", photoPrintingIntentCapability),
                new XAttribute("PageImageableAreaOriginHeight", pageImageableAreaOriginHeight),
                new XAttribute("PageImageableAreaOriginWidth", pageImageableAreaOriginWidth),
                new XAttribute("PageImageableAreaExtentHeight", pageImageableAreaExtentHeight),
                new XAttribute("PageImageableAreaExtentWidth", pageImageableAreaExtentWidth));
            }
        }

        public override string ToString()
        {
            string sXml = "";
            sXml += (" CollationCapability=\"" + this.collationCapability + @"""");
            sXml += (" MaxCopyCount=\"" + this.maxCopyCount + @"""");
            sXml += (" DeviceFontSubstitutionCapability=\"" + this.deviceFontSubstitutionCapability + @"""");
            sXml += (" DuplexingCapability=\"" + this.duplexingCapability + @"""");
            sXml += (" InputBinCapability=\"" + this.inputBinCapability + @"""");
            sXml += (" OutputColorCapability=\"" + this.outputColorCapability + @"""");
            sXml += (" OutputQualityCapability=\"" + this.outputQualityCapability + @"""");
            sXml += (" PageBorderlessCapability=\"" + this.pageBorderlessCapability + @"""");
            sXml += (" PageOrderCapability=\"" + this.pageOrderCapability + @"""");
            sXml += (" PageOrientationCapability=\"" + this.pageOrientationCapability + @"""");
            sXml += (" PageResolutionCapability=\"" + this.pageResolutionCapability + @"""");
            sXml += (" PageResolutionCapabilityDpiX=\"" + this.pageResolutionCapability + @"""");
            sXml += (" PageResolutionCapabilityDpiY=\"" + this.pageResolutionCapability + @"""");
            sXml += (" PageScalingFactorRangeMinimum=\"" + this.pageScalingFactorRangeMinimum + @"""");
            sXml += (" PageScalingFactorRangeMaximum=\"" + this.pageScalingFactorRangeMaximum + @"""");
            sXml += (" PhotoPrintingIntentCapability=\"" + this.photoPrintingIntentCapability + @"""");
            sXml += (" PageImageableAreaOriginHeight=\"" + this.pageImageableAreaOriginHeight + @"""");
            sXml += (" PageImageableAreaOriginWidth=\"" + this.pageImageableAreaOriginWidth + @"""");
            sXml += (" PageImageableAreaExtentHeight=\"" + this.pageImageableAreaExtentHeight + @"""");
            sXml += (" PageImageableAreaExtentWidth=\"" + this.pageImageableAreaExtentWidth + @"""");
            sXml += " />";
            return sXml;
        }

        private List<string> AdjustCapability(int iMask, List<string> sArr)
        {
            List<string> sArray = sArr;
            if (iMask == 0)
            {
                sArray.RemoveAt(0);
                if (sArray.Count == 0)
                    sArray.Add("Feature not available");
                return sArray; ;
            }
            else
                for (int i = sArray.Count - 1; i >= 0; i--)
                {
                    int ii = 1 << i;
                    if ((iMask & ii) == 0)
                        sArray.RemoveAt(i);
                }

            if (sArray.Count == 0)
                sArray.Add("Unknown");
            return sArray;
        }

    }

    public class Printers : List<Printer>
    {
        public Printers()
        {
        }

        public void Load(string strXML)
        {
            string[] sSepQueue = new string[1] { "|||" };
            string[] sSepElements = new String[1] { "|" };
            List<string> sq = new List<string>();
            List<string> spt = new List<string>();
            List<string> spc = new List<string>();

            string[] sQueues = strXML.Split(sSepQueue, StringSplitOptions.RemoveEmptyEntries);
            foreach (string sQueue in sQueues)
            {
                string[] sSplits = sQueue.Split(sSepElements, StringSplitOptions.RemoveEmptyEntries);
                sq.Add(sSplits[0]);
                spt.Add(sSplits[1]);
                spc.Add(sSplits[2]);
            }

            string strX = "<PRINTERS>" + Environment.NewLine;
            foreach (string str in sq)
                strX += str;
            strX += (Environment.NewLine + "</PRINTERS>");

            var vPrinter = from s in XElement.Parse(strX).Elements("PRINTER") select new Printer(s);
            AddRange(vPrinter);

            int i = 0;
            foreach (Printer p in this)
            {
                string xString = "<PRINTTICKETS>" + spt[i].ToString() + "</PRINTTICKETS>";
                var v = from s in XElement.Parse(xString).Elements("PRINTTICKET") select new PrintTicket(s);
                p.printTicket = (PrintTicket)v.First();

                xString = "<PRINTCAPABILITIES>" + spc[i].ToString() + "</PRINTCAPABILITIES>";
                var vv = from s in XElement.Parse(xString).Elements("PRINTCAPABILITY") select new PrinterCapability(s);
                p.printerCapability = (PrinterCapability)vv.First();
                i++;
            }
        }
    }
}
